package com.lam.framework.datasource.config;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.Environment;

import com.alibaba.druid.pool.DruidDataSource;
import com.lam.common.exception.BaseException;
import com.lam.common.utils.NumberUtil;
import com.lam.framework.datasource.DataSourceMap;

/**
 * @author lam
 *
 */
public abstract class BaseDynamicDataSource {

	protected Logger logger = LoggerFactory.getLogger(getClass());
	
	public static final String DS_SUFFIX = "DataSource";
//	public static final String DS_PREFIX = "datasource.";

	@Autowired
	protected Environment env; 
	
	public abstract DataSourceMap createDataSourceMap();
	
	/**
	 * 配置一个连接在池中最大最小生存的时间，单位是毫秒，此处为修订<b> com.alibaba.druid.pool.DruidDataSource </b>连接池初始化的Bug，
	 * 不调用此方法的话，系统有时启动会报 <b>maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis 异常</b>
	 * @param dataSource
	 * @return
	 */
	protected DruidDataSource setEvictableIdleTime(DruidDataSource dataSource) {
		String prefix = getPrefix();
		dataSource.setMinEvictableIdleTimeMillis(NumberUtil.toLongVal(env.getProperty(prefix+".minEvictableIdleTimeMillis"), 300000));
		dataSource.setMaxEvictableIdleTimeMillis(NumberUtil.toLongVal(env.getProperty(prefix+".maxEvictableIdleTimeMillis"), 900000));
		return dataSource;
	}
	
	protected String getPrefix() {
		
		Method superMethod = null;
		try {
			StackTraceElement dataSourceConfigStackTraceElement = Thread.currentThread().getStackTrace()[3];
			Class<?> clazz = Class.forName(dataSourceConfigStackTraceElement.getClassName());
			String methodName = dataSourceConfigStackTraceElement.getMethodName();
			Method[] methods = clazz.getDeclaredMethods();
			
			for (Method method : methods) {
				if(method.getName().equals(methodName)) {
					superMethod = method;
					break;
				}
			}
		} catch (ClassNotFoundException e) {
			logger.error(e.getMessage(), e);
			throw new BaseException("数据库配置解析异常");
		}
		if(superMethod == null) {
			throw new BaseException("数据库配置解析异常");
		}
		return superMethod.getAnnotation(ConfigurationProperties.class).prefix();	
	}

}
